package com.jiantong.web.open.app.work;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.jiantong.web.core.enums.ExceptionCode;
import com.jiantong.work.dto.AnimalMarkDto;
import com.jiantong.work.enums.AnimalMarkStatus;
import com.jiantong.work.model.AnimalMark;
import com.jiantong.work.service.AnimalMarkReadService;
import com.jiantong.work.service.AnimalMarkWriteService;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.annotations.OpenBean;
import io.terminus.pampas.openplatform.annotations.OpenMethod;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by mz on 6/7/17.
 *
 */
@OpenBean
@Slf4j
public class AnimalMarkApis {

    @RpcConsumer
    private AnimalMarkWriteService animalMarkWriteService;

    @RpcConsumer
    private AnimalMarkReadService animalMarkReadService;

    @OpenMethod(
            key = "find.animal.mark.by.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET
    )
    public AnimalMark findById(Long id){

        if(id == null){
            log.error("id should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "id should be not null");
        }

        Response<AnimalMark> response = animalMarkReadService.findById(id);

        if(!response.isSuccess()){
            log.error("failed to find animal mark by id = {}",id);
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    "failed to find animal mark");
        }
        return response.getResult();
    }

    /**
     * 根据养殖场id
     * @param pageNo
     * @param pageSize
     * @param status
     * @param batch
     * @param breedFactoryId
     * @param breedFactoryName
     * @return
     */
    @OpenMethod(
            key = "paging.animal.mark",
            paramNames = {"pageNo","pageSize","status","batch","breedFactoryId","breedFactoryName"},
            httpMethods = RequestMethod.GET
    )
    public Paging<AnimalMark> animalMarkPaging(Integer pageNo,
                                               Integer pageSize ,
                                               Integer status,
                                               String batch,
                                               Long breedFactoryId,
                                               String breedFactoryName){
        Map<String , Object> map = Maps.newHashMap();
        if(status != null){
            map.put("status",status);
        }

        if(batch != null && !batch.trim().isEmpty()){
            map.put("batch",batch);
        }

        if(breedFactoryId != null){
            map.put("breedFactoryId",breedFactoryId);
        }

        if(breedFactoryName != null && !breedFactoryName.trim().isEmpty()){
            map.put("breedFactoryName",breedFactoryName);
        }
        Response<Paging<AnimalMark>> response = animalMarkReadService.pagingAnimalMak(pageNo,pageSize,map);

        if(!response.isSuccess()){
            log.error("failed to paging animal marks");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),"failed to paging animal marks");
        }

        return response.getResult();
    }

    /**
     * 根据养殖场id 用于畜禽出场时选择耳标list
     * @param pageNo
     * @param pageSize      数量
     * @param statuses
     * @param batch
     * @param markNumber    起始耳标号
     * @param breedFactoryId
     * @param breedFactoryName
     * @return
     */
    @OpenMethod(
            key = "paging.select.animal.mark",
            paramNames = {"pageNo","pageSize","statuses","batch","markNumber","breedFactoryId","breedFactoryName"},
            httpMethods = RequestMethod.GET
    )
    public Paging<AnimalMark> animalSelectMarkPaging(Integer pageNo,
                                               Integer pageSize ,
                                               List<Integer> statuses,
                                               String batch,
                                               String markNumber,
                                               Long breedFactoryId,
                                               String breedFactoryName){
        Map<String , Object> map = Maps.newHashMap();
        if(statuses != null){
            map.put("statuses",statuses);
        }

        if(batch != null && !batch.trim().isEmpty()){
            map.put("batch",batch);
        }

        if(!Strings.isNullOrEmpty(markNumber)){
            map.put("markNumber",markNumber);
        }

        if(breedFactoryId != null){
            map.put("breedFactoryId",breedFactoryId);
        }

        if(breedFactoryName != null && !breedFactoryName.trim().isEmpty()){
            map.put("breedFactoryName",breedFactoryName);
        }
        map.put("isSelected",1);
        Response<Paging<AnimalMark>> response = animalMarkReadService.pagingSelectAnimalMak(pageNo,pageSize,map);

        if(!response.isSuccess()){
            log.error("failed to paging select animal marks");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),"failed to paging select animal marks");
        }

        return response.getResult();
    }


    /**
     * 根据养殖场名字分页查询每个散户养殖场的信息
     * @param pageNo
     * @param pageSize
     * @param breedFactoryName
     * @return
     */
    @OpenMethod(
            key = "paging.by.breedFactoryName.find.animal.mark",
            paramNames = {"pageNo","pageSize","breedFactoryName"},
            httpMethods = RequestMethod.GET
    )
    public Paging<AnimalMarkDto> animalMarkPaging(Integer pageNo,  Integer pageSize,String breedFactoryName){
        Map<String , Object> map = Maps.newHashMap();
        if(breedFactoryName != null){
            map.put("breedFactoryName",breedFactoryName);
        }
        Response<Paging<AnimalMarkDto>> response = animalMarkReadService.pagingAnimalMakByBreedFactoryName(pageNo,pageSize,map);
        if(!response.isSuccess()){
            log.error("failed to paging animal marks by breed factory name");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),"failed to paging animal marks by breed factory name");
        }
        return response.getResult();
    }



    /**
     *
     * @param animalMark
     * @return
     */
    @OpenMethod(
            key = "create.an.animal.mark",
            paramNames = {"animalMark"},
            httpMethods = RequestMethod.POST
    )
    public Long createAnimalMark(AnimalMark animalMark){
        if(animalMark == null){
            log.error("this object should be not null");
            throw new OPClientException(ExceptionCode.OBJECT_NOT_EXIST.value(),
                    "this object should be not null");
        }
        String batch = new Date().getTime()+"";
        animalMark.setBatch(batch);
        Integer isSelected = 1;
        animalMark.setIsSelected(isSelected);
        Response<Long> response = animalMarkWriteService.createAnimalMark(animalMark);
        if(!response.isSuccess()){
            log.error("create animal mark");
            throw new OPServerException(ExceptionCode.DATA_WRITE_FAIL.value(),"create animal mark");
        }
        return response.getResult();
    }

    @OpenMethod(
            key = "create.multi.animal.mark",
            paramNames = {"animalMarkMaps"},
            httpMethods = RequestMethod.POST
    )
    public Integer createMultiAnimalMark(List<Map<String , Object>> animalMarkMaps){
        if(animalMarkMaps == null || animalMarkMaps.isEmpty()){
            log.error("this objects should be not null");
            throw new OPClientException(ExceptionCode.OBJECT_NOT_EXIST.value(),
                    "this objects should be not null");
        }
        //统一添加批次号
        String batch = new Date().getTime()+"";
        Integer isSelected = 1;
        Date createdAt = new Date();
        List<AnimalMark> animalMarkList = new ArrayList<>();
        for (Map<String , Object> map : animalMarkMaps) {
            AnimalMark animalMark = new AnimalMark();
            animalMark.setBatch(batch);
            animalMark.setBreedFactoryId(new Long((Integer) map.get("breedFactoryId")));
            animalMark.setBreedFactoryName((String) map.get("breedFactoryName"));
            animalMark.setMarkNumber((String) map.get("markNumber"));
            animalMark.setMarkType((Integer) map.get("markType"));
            animalMark.setStatus(1);
            animalMark.setIsSelected(isSelected);
            animalMark.setCreatedAt(createdAt);
            animalMarkList.add(animalMark);
        }

        Response<Integer> response = animalMarkWriteService.createAnimalMarks(animalMarkList);
        if(!response.isSuccess()){
            log.error("create multi animal mark");
            throw new OPServerException(ExceptionCode.DATA_WRITE_FAIL.value(),
                    "create multi animal mark");
        }
        return response.getResult();
    }

    @OpenMethod(
            key = "update.animal.mark",
            paramNames = {"animalMark"},
            httpMethods = RequestMethod.PUT
    )
    public Boolean updateAnimalMark(AnimalMark animalMark){
        if(animalMark.getId() == null){
            log.error("id should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "id should be not null");
        }
        Response<Boolean> response = animalMarkWriteService.updateAnimalMark(animalMark);
        if(!response.isSuccess()){
            log.error("failed to update animal mark");
            throw new OPServerException(ExceptionCode.DATA_UPDATE_FAIL.value(),
                    "failed to update animal mark");
        }
        return response.getResult();
    }

    /**
     * 根据耳标号更新
     * @param animalMark
     * @return
     */
    @OpenMethod(
            key = "update.animal.mark.by.mark.number",
            paramNames = {"animalMark"},
            httpMethods = RequestMethod.PUT
    )
    public Boolean updateAnimalMarkByNumber(AnimalMark animalMark){
        if(animalMark.getMarkNumber() == null){
            log.error("markNumber id should be not null");
            throw new OPClientException(ExceptionCode.PARAMETER_NOT_EXIST.value(),
                    "markNumber id should be not null");
        }
        Response<Boolean> response = animalMarkWriteService.updateAnimalMarkByNumber(animalMark);
        if(!response.isSuccess()){
            log.error("failed to update animal mark");
            throw new OPServerException(ExceptionCode.DATA_UPDATE_FAIL.value(),
                    "failed to update animal mark");
        }
        return response.getResult();
    }

    /**
     * 根据养殖场ID和残缺起始耳标号模糊查询出一个起始耳标号list
     * @param startAnimalMark
     * @param breedFactoryId
     * @return
     */
    @OpenMethod(
            key = "find.animal.startAnimalMark.by.startAnimalMark",
            paramNames = {"pageNo","pageSize","startAnimalMark","breedFactoryId"},
            httpMethods = RequestMethod.GET
    )
    public Paging<AnimalMark> findByMark(Integer pageNo,  Integer pageSize,String startAnimalMark,Long breedFactoryId){

        if (breedFactoryId == null){
            log.error("breedFactoryId should be not null");
            throw new OPClientException(ExceptionCode.PARAMETER_NOT_EXIST.value(),
                    "breedFactoryId should be not null");
        }
        Map<String, Object> map = Maps.newHashMap();
        map.put("breedFactoryId",breedFactoryId);
        map.put("status", AnimalMarkStatus.DEPOSITED.value());//规定只查询状态为1(库存)的耳标号

        //如果起始耳标为null,默认查询排列靠前的十个状态为入库的耳标
        if(startAnimalMark == null || startAnimalMark.equals("")){
            Response<List<AnimalMark>> response = animalMarkReadService.findByMarkIsNull(map);
            if(!response.isSuccess()){
                log.error("failed to find animal mark by id = {}",startAnimalMark);
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                        "failed to find animal mark");
            }
            return new Paging(10L,response.getResult());
        }
        map.put("startAnimalMark",startAnimalMark);

        //如果起始耳标不为null,根据残缺耳标号模糊查询出一个耳标号list
        Response<Paging<AnimalMark>> response = animalMarkReadService.findByMark(pageNo,pageSize,map);
        if(!response.isSuccess()){
            log.error("failed to find animal mark by id = {}",startAnimalMark);
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                    "failed to find animal mark");
        }
        return response.getResult();
    }


    /**
     * 更新一堆animalMarks
     * @param animalMarkList
     * @return
     *
    <if test="status != null">status = #{status},</if>
    <if test="woreAt != null">wore_at = #{woreAt},</if>
    <if test="outedAt != null">outed_at = #{outedAt}</if>
     */
    @OpenMethod(
            key = "update.animal.marks",
            paramNames = {"animalMarks",},
            httpMethods = RequestMethod.PUT
    )
    public Boolean updateAnimalMark(List<AnimalMark> animalMarkList){
        Map<String,Object> map = Maps.newHashMap();
        List<Long> ids = new ArrayList<>(animalMarkList.size());
        for (AnimalMark animalMark: animalMarkList) {
            if (animalMark.getId()==null){
                log.error("id should be not null");
                throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                        "id should be not null");
            }
            ids.add(animalMark.getId());
        }
        map.put("ids",ids);
        map.put("status",AnimalMarkStatus.USE.value());
        Response<Boolean> response = animalMarkWriteService.updates(map);
        if(!response.isSuccess()){
            log.error("failed to update animal mark");
            throw new OPServerException(ExceptionCode.DATA_UPDATE_FAIL.value(),
                    "failed to update animal mark");
        }
        return response.getResult();
    }

    /**
     * 根据耳标号查询耳标号的具体信息（目前产地检疫出库的时候）
     * @param markNumber 耳标号(全)
     * @return 是否成功
     */
    @OpenMethod(
            key = "find.by.mark.number.is.exist",
            paramNames = {"markNumber"},
            httpMethods = RequestMethod.GET
    )
    public AnimalMark findByMarkNumber(String markNumber){
        if(markNumber == null || markNumber.trim().isEmpty() || markNumber.trim().length() != 15){
            log.error("markNumber should be not null");
            throw new OPClientException(ExceptionCode.PARAMETER_NOT_EXIST.value(),"markNumber should be not null");
        }
        Response<AnimalMark> response = animalMarkReadService.findByMarkNumber(markNumber);
        if(!response.isSuccess()){
            log.error("failed to find mark number");
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
        }

        return response.getResult();
    }
}
